﻿using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Dysmsapi.Model.V20170525;
using System;
using System.Collections.Generic;
using System.Text;

namespace Adnc.Application.Shared.AliyunAudit
{
    public class Sms
    {
        /// <summary>
        /// 获取阿里云 accessKeyId
        /// </summary>
        public string accessKeyId { get; set; }
        /// <summary>
        /// 获取阿里云 accessKeySecret
        /// </summary>
        public string accessKeySecret { get; set; }
        /// <summary>
        /// 获取阿里云 短信签名
        /// </summary>
        public string signature { get; set; }
        //产品名称:云通信短信API产品,开发者无需替换
        public string product { get; } = "Dysmsapi";
        //产品域名,开发者无需替换
        public string domain { get; } = "dysmsapi.aliyuncs.com";
        public Sms(AliyunOptions option)
        {
            accessKeyId = option.AccessKeyId;
            accessKeySecret = option.AccessKeySecret;
        }



        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="tele">电话号码</param>
        /// <param name="signName">签名</param>
        /// <param name="smsCodeTemp">模板编码</param>
        /// <param name="smsCodeTempJson">模板对应内容</param>
        /// <param name="func">委托方法</param>
        /// <param name="erroe">异常信息</param>
        /// <returns></returns>
        public bool SendSms(string tele, string signName, string smsCodeTemp, string smsCodeTempJson, Action<SendSmsResponse, SendSmsRequest> func, out string erroe)
        {

            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            profile.AddEndpoint("cn-hangzhou", "cn-hangzhou", product, domain,false);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            SendSmsRequest request = new SendSmsRequest();
            SendSmsResponse res = null;
            //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
            request.PhoneNumbers = tele;
            //必填:短信签名-可在短信控制台中找到
            request.SignName = signName;
            //必填:短信模板-可在短信控制台中找到
            request.TemplateCode = smsCodeTemp;
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.TemplateParam = smsCodeTempJson;
            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
            request.OutId = "yourOutId";
            //请求失败这里会抛ClientException异常
            res = acsClient.GetAcsResponse(request);
            func?.Invoke(res, request);
            switch (res.Code)
            {
                case "OK":
                    erroe = "发送成功";
                    return true;
                case "isp.RAM_PERMISSION_DENY"://RAM权限DENY
                    erroe = "RAM权限DENY";
                    return false;
                case "isv.OUT_OF_SERVICE"://业务停机
                    erroe = "业务停机";
                    return false;
                case "isv.PRODUCT_UN_SUBSCRIPT"://未开通云通信产品的阿里云客户
                    erroe = "未开通云通信产品的阿里云客户";
                    return false;
                case "isv.PRODUCT_UNSUBSCRIBE"://产品未开通
                    erroe = "产品未开通";
                    return false;
                case "isv.ACCOUNT_NOT_EXISTS"://账户不存在
                    erroe = "账户不存在";
                    return false;
                case "isv.ACCOUNT_ABNORMAL"://账户异常
                    erroe = "账户异常";
                    return false;
                case "isv.SMS_TEMPLATE_ILLEGAL"://短信模板不合法
                    erroe = "短信模板不合法";
                    return false;
                case "isv.SMS_SIGNATURE_ILLEGAL"://短信签名不合法
                    erroe = "短信签名不合法";
                    return false;
                case "isv.INVALID_PARAMETERS"://参数异常
                    erroe = "参数异常";
                    return false;
                case "isp.SYSTEM_ERROR"://系统错误
                    erroe = "系统错误";
                    return false;
                case "isv.MOBILE_NUMBER_ILLEGAL"://非法手机号
                    erroe = "非法手机号";
                    return false;
                case "isv.MOBILE_COUNT_OVER_LIMIT"://手机号码数量超过限制
                    erroe = "手机号码数量超过限制";
                    return false;
                case "isv.TEMPLATE_MISSING_PARAMETERS"://模板缺少变量
                    erroe = "模板缺少变量";
                    return false;
                case "isv.BUSINESS_LIMIT_CONTROL"://业务限流
                    erroe = "业务限流";
                    return false;
                case "isv.INVALID_JSON_PARAM"://JSON参数不合法，只接受字符串值
                    erroe = "JSON参数不合法，只接受字符串值";
                    return false;
                case "isv.BLACK_KEY_CONTROL_LIMIT"://黑名单管控
                    erroe = "黑名单管控";
                    return false;
                case "isv.PARAM_LENGTH_LIMIT"://参数超出长度限制
                    erroe = "参数超出长度限制";
                    return false;
                case "isv.PARAM_NOT_SUPPORT_URL"://不支持URL
                    erroe = "不支持URL";
                    return false;
                case "isv.AMOUNT_NOT_ENOUGH"://账户余额不足
                    erroe = "账户余额不足";
                    return false;
                default:
                    erroe = "其它异常";
                    return false;

            }
        }

        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="tele">电话号码</param>
        /// <param name="signName">签名</param>
        /// <param name="smsCodeTemp">模板编码</param>
        /// <param name="smsCodeTempJson">模板对应内容</param>
        /// <param name="func">委托方法</param>
        /// <param name="erroe">异常信息</param>
        /// <returns></returns>
        public SendSmsResponse SendSms(string tele, string signName, string smsCodeTemp, string smsCodeTempJson)
        {

            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            profile.AddEndpoint("cn-hangzhou", "cn-hangzhou", product, domain, false);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            SendSmsRequest request = new SendSmsRequest();
            //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
            request.PhoneNumbers = tele;
            //必填:短信签名-可在短信控制台中找到
            request.SignName = signName;
            //必填:短信模板-可在短信控制台中找到
            request.TemplateCode = smsCodeTemp;
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.TemplateParam = smsCodeTempJson;
            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
            request.OutId = "yourOutId";
            //请求失败这里会抛ClientException异常
            return acsClient.GetAcsResponse(request);
        }
    }
}
